Wire recommendations.v1 into the UI render surface and exports - #158
Merged
Conversation
The backend has been projecting Phase 2 device cards into the frozen, schema-validated, citation-gated recommendations.v1 envelope (ADR 0003) and attaching it to every producer_summary interpretation — but no UI code read it. The cards rendered from the raw arrays only, leaving the validated projection decorative. This makes the envelope load-bearing on three surfaces: - New reader service (src/services/recommendationsContract.ts): indexes the envelope so each raw device card can be paired with its validated contract entry. Pairing is by (device, parameter, normalized value) — device+parameter alone is ambiguous when Phase 2 repeats a pair with different values, and a wrong pairing would surface a confidently-wrong working range. The value parser is a deliberate TS mirror of the backend's parse_value (same cross-boundary duplication pattern as audio_mime.py / audioFile.ts). - Mix Chain + Patch cards: cards backed by a contract entry carry a "Validated" chip in the header and, expanded, a recommendations.v1 block showing the normalized value and the published working range. Cards without a match are exactly the uncited cards the projection refused — the citation gate made visible. Synthetic frontend-derived cards (limiter fallback, stereo width, MIDI Clip Guide) never match by construction. - Markdown export: a "Validated Recommendations (recommendations.v1)" table with device, parameter, normalized value, working range, and cited measurements. (The JSON export already carried the envelope verbatim inside phase2.) Verified: tsc clean, full Vitest suite 782 passed, production build green. Playwright smoke not runnable in this environment (cdn.playwright.dev blocked by network allowlist). https://claude.ai/code/session_01Q8cG71HowqrHxa7dXJ5f3a
slittycode
force-pushed
the
claude/hopeful-galileo-o5nnxp
branch
from
June 11, 2026 22:19
03e62b6 to
60d7f43
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The backend projects Phase 2 device cards into the frozen, schema-validated, citation-gated
recommendations.v1envelope (ADR 0003) and attaches it to every producer_summary interpretation — but the UI never read it.RecommendationsContractexisted intypes/interpretation.tsas a definition only; the cards rendered from the raw arrays. This PR makes the envelope load-bearing on the user-facing surface.What changed
New reader service —
apps/ui/src/services/recommendationsContract.tsIndexes the envelope so each raw device card can be paired with its validated contract entry. Pairing is by (device, parameter, normalized value): device+parameter alone is ambiguous when Phase 2 repeats a pair with different values, and a wrong pairing would surface a confidently-wrong working range — the exact failure mode the warn-only catalogue gate exists to prevent. The value parser is a deliberate TS mirror of the backend's
parse_value(same cross-boundary duplication pattern asaudio_mime.py/audioFile.ts), with a test case table pinned to the backend's documented examples so drift surfaces in CI.Mix Chain + Patch cards (
analysisResultsViewModel.ts,AnalysisResults.tsx)Card view models now carry
contractEntries. Cards backed by an entry render a "✓ Validated" chip in the header and, when expanded, arecommendations.v1block with the normalized value and the contract's published working range (net-new information — the raw value string already renders in the parameter grid). Cards without a match are exactly the uncited cards the projection refused to admit, so the badge is the citation gate (PURPOSE.md invariant #2) made visible. Synthetic frontend-derived cards (limiter fallback, stereo width, MIDI Clip Guide) never match by construction.Markdown export (
exportUtils.ts)New "Validated Recommendations (recommendations.v1)" table: device, parameter, normalized value, working range, cited measurements. The JSON export already carried the envelope verbatim inside
phase2; no change needed there.Not changed: the applied-recommendations tracker keeps its positional card ids — rekeying to contract entries would orphan existing localStorage progress, and the contract deliberately excludes uncited cards that still render (and still need tracking).
Verification
npm run lint(tsc) — cleannpm test— 782 passed, 4 skipped (includes newrecommendationsContract.test.ts: parser mirror table, value-aware disambiguation, citation-gate absence; plus view-model and export coverage)npm run build— greencdn.playwright.devblocked by the environment network allowlist) — relying on CI for the smoke gatehttps://claude.ai/code/session_01Q8cG71HowqrHxa7dXJ5f3a
Generated by Claude Code